<!--
 * @Author: Songjq
 * @Date: 2021-08-13 17:03:47
 * @Desscription:
-->
<template>
  <div
    class="left-tree"
    :class="sourceType"
  >
    <div class="fixed">
      <div
        v-if="showSearch"
        class="head-container"
      >
        <el-input
          v-model="deptName"
          clearable
          size="mini"
          placeholder="输入名称搜索"
          prefix-icon="el-icon-search"
          @keyup.enter.native="getNodeSearchInit"
          @clear="init"
        />
      </div>
    </div>
    <div class="ui-pdl-24">
      <el-checkbox
        v-if="isChecked"
        v-model="checkStrictly"
      >联动子级</el-checkbox>
    </div>
    <h3 v-if="false">组织架构</h3>
    <div class="out_tree">
      <el-tree
        ref="tree"
        :check-strictly="!checkStrictly"
        :default-expand-all="defaultExpandAll"
        :data="deptDatas"
        :props="defaultProps"
        :node-key="nodekey"
        :show-checkbox="isChecked"
        highlight-current
        :expand-on-click-node="false"
        :default-checked-keys="defaultCheckedKeys"
        :default-expanded-keys="defaultExpandedKeys"
        @node-click="handleNodeClick"
        @check="checkChange"
        @node-expand="(node) => {nodeExpand(node)}"
      >
        <span
          class="custom-tree-node"
          slot-scope="{ node}"
        >
          <span>{{ node.label }}</span>
        </span>
      </el-tree>
    </div>
    <div
      v-if="loading"
      v-loading="loading"
      class="loading"
    />
  </div>
</template>

<script>
import { getMenusTree, getMenusTreeAll } from "@http/system/menu.js";
export default {
  name: "OrgTree",
  props: {
    showSearch: {
      // 展示检索
      type: Boolean,
      default: false,
    },
    defaultExpandAll: {
      // 默认展开所有节点
      type: Boolean,
      default: false,
    },
    isChecked: {
      // 树节点是否可选
      type: Boolean,
      default: false,
    },
    isAutoInit: {
      // 是否自动初始化
      type: Boolean,
      default: true,
    },
    isLazy: {
      // 是否自动初始化
      type: Boolean,
      default: true,
    },
    defaultCheckedKeys: {
      // 默认勾选的节点数组
      type: Array,
      default: function () {
        return [];
      },
    },
    sourceType: {
      type: String,
      default: "menus",
    },
  },
  data() {
    return {
      deptName: "",
      isAllChildren: false, // 包含子集
      tagId: "",
      tagOptions: [],
      node: null,
      treeType: "tree", // 树节点类型
      loading: false,
      deptDatas: [],
      defaultExpandedKeys: [], // 默认展开的树节点
      defaultProps: {
        label: "label",
        children: "children",
        isLeaf: "leaf",
      },
      checkStrictly: false, // 联动子级
    };
  },
  computed: {
    // 绑定key 类型
    nodekey() {
      let str = "id";
      if (this.sourceType == "power") {
        str = "permission";
      }
      return str;
    },
  },
  created() {
    this.$nextTick(() => {
      if (this.isAutoInit) {
        this.init();
      }
    });
  },
  methods: {
    // 初始化树节点
    init() {
      this.deptName = "";
      this.deptDatas = [];
      this.defaultExpandedKeys = [];
      this.loadNodes({ id: "0" }); // 加载请求树节点的方法
    },

    // 展开树节点
    nodeExpand(node) {
      if (this.isLazy) {
        this.getMenusTree(node);
      }
    },

    // 加载树节点
    async loadNodes(node) {
      if (this.isLazy) {
        this.getMenusTree(node);
      } else {
        this.getMenusTreeAll();
      }
    },

    // 返回所有数据
    getMenusTreeAll() {
      this.loading = true;
      getMenusTreeAll().then((res) => {
        this.loading = false;
        this.deptDatas = res.data;
      });
    },

    // 懒加载树节点数据
    getMenusTree(node) {
      this.loading = true;
      getMenusTree({
        parentId: node.id,
      }).then((res) => {
        this.loading = false;
        if (!res || res.data.length === 0) {
          this.getChildrens(this.deptDatas, node.id, res.data);
          return;
        }

        // 解决节点展示空白的问题
        res.data.forEach((val) => {
          val.children = [{}];
          this.defaultExpandedKeys.forEach((value, index) => {
            if (value === val.id) {
              this.defaultExpandedKeys.splice(index, 1);
            }
          });
        });

        if (node.id === "0") {
          res.data.forEach((val) => {
            this.deptDatas.push(val);
          });
        } else {
          this.getChildrens(this.deptDatas, node.id, res.data);
        }
      });
    },

    // 通过父级ID 拼接组织树
    getChildrens(nodes, pid, arr) {
      nodes.forEach((val) => {
        if (val.id === pid) {
          val.children = arr;
        } else if (val.children && val.children.length > 0) {
          this.getChildrens(val.children, pid, arr);
        }
      });
    },

    // 切换部门
    handleNodeClick(data) {
      this.$emit("treeItemClick", data);
    },

    // 树节点检索
    getNodeSearchInit() {
      const verObj = this.verifyKeyword(this.deptName);
      if (verObj.isNotGo) {
        this.$notify({
          title: verObj.tips,
          type: "warning",
        });
        return;
      }

      if (this.deptName === "") {
        this.init();
        return;
      }

      this.getNodeSearch(this.deptName, this.tagId);
    },

    // 复选操作
    checkChange(data) {
      this.$emit("treeItemChecked", data);
      this.$emit("getCheckedKeys", this.$refs.tree.getCheckedKeys());
    },

    // 通过关键字检索树节点
    getNodeSearch(keyword, tagId) {
      this.deptDatas = [];
      this.loading = true;
      this.defaultExpandedKeys = [];
    },

    // 设置默认展开
    setDefaultExpandedKeys() {
      if (this.deptDatas.length > 0) {
        this.deptDatas.forEach((val) => {
          this.defaultExpandedKeys.push(val.id);
        });
      }
    },
  },
};
</script>

<style scoped lang="scss">
.left-tree {
  box-sizing: border-box;
  height: calc(100vh - 126px);
  position: relative;
  display: flex;
  flex-direction: column;
  &.menus {
    width: 490px;
  }
  &.power {
    width: 100%;
    padding: 10px;
  }

  h3 {
    font-weight: 600;
    color: #333333;
    padding-bottom: 10px;
  }
  .head-container {
    .el-input {
      background: #f4f5f6;
      border: none;
    }
    .el-input__inner {
      border: none !important;
    }
  }

  .out_tree {
    flex: 1;
    width: 100%;
    overflow-x: auto;
    .tree-content {
      overflow-y: auto;
    }
  }

  .fixed {
    top: 0;
    left: 0;
    width: 100%;
    position: absolute;
  }

  .loading {
    width: 100%;
    height: 100%;
    margin-top: 0px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 99;
  }
}
.el-tree {
  min-width: 100%;
  display: inline-block !important;
}
</style>
